﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WD.Classes;
using WDutils;

namespace WD
{
    public partial class Report : Form
    {
        public const double WORKING_HOUR_OVERTIME_TRESHOLD = 8.3;
        public const double WORKING_HOUR_UNDERTIME_TRESHOLD = 7.7;

        public Report()
        {
            InitializeComponent();
        }

        private void UpdateProgreeBar(VerticalProgressBar VPB, Label LDetail, double doubleValue, bool boolIsWeekend, long longTimeDiff, long longTimeStampDay)
        {
            VPB.Value = (int)(doubleValue);
            if (!boolIsWeekend)
            {
                if (doubleValue > 100.0 / 12.0 * WORKING_HOUR_OVERTIME_TRESHOLD) VPB.ForeColor = Color.Red;
                else
                {
                    if (doubleValue < 100.0 / 12.0 * WORKING_HOUR_UNDERTIME_TRESHOLD) VPB.ForeColor = Color.Yellow;
                    else VPB.ForeColor = Color.Green;
                }
            }
            else
            {
                VPB.ForeColor = Color.Red;
            }

            double dHours = longTimeDiff / 3600.0;

            TT_Report.SetToolTip(VPB, "Time : " + dHours.ToString("#.##"));
            LDetail.Text = Utils.Unix.DateTimeFromUnixTimestampSeconds(longTimeStampDay).ToLongDateString() + "\r\n" + dHours.ToString("#.##") + " hours";

        }

        private void Report_Load(object sender, EventArgs e)
        {
            VPB_Mon.Value = 0;
            VPB_Tue.Value = 0;
            VPB_Wed.Value = 0;
            VPB_Thu.Value = 0;
            VPB_Fri.Value = 0;
            VPB_Sat.Value = 0;
            VPB_Sun.Value = 0;

            long longTimeStamp_BeginningOfDay = Utils.Unix.GetUnixTimestampSecondsFromDateTime(
                Utils.Unix.GetDateTime_BeginningOfDay(Utils.Unix.GetDateTime_BeginningOfWeek(DTP_Filter.Value))) + 0 * 3600;

            long longTimeStamp_EndOfDay = longTimeStamp_BeginningOfDay;

            long lWeekTotalHours = 0;

            for (int indexDays = 0; indexDays < 7; indexDays++)
            {
                longTimeStamp_EndOfDay = longTimeStamp_BeginningOfDay + (indexDays * 24 * 3600);

                List<double> listDouble = new List<double>();

                ActivityLogEvents.GetActivityLogWorkingHoursPerDay EventGetListWorkHours = new ActivityLogEvents.GetActivityLogWorkingHoursPerDay();
                EventGetListWorkHours.setDay(Utils.Unix.DateTimeFromUnixTimestampSeconds(longTimeStamp_EndOfDay));
                listDouble = (List<double>) EventGetListWorkHours.Request();

                long longTimeDiff = (long)listDouble[1];

                int intDayOfWeek_ = indexDays <= 5 ? indexDays+1 : 0;

                lWeekTotalHours += longTimeDiff;

                double doublePercentPerSecond = 100.0 / 12.0 / 3600.0; // 12 h = 100% -> 1 h = 100/12 -> 3600 sec = 100/12 -> 1 sec = REZULT - index
                double doubleCurrentDayPercent = (double)(longTimeDiff) * doublePercentPerSecond;
                if (doubleCurrentDayPercent > 100.0) doubleCurrentDayPercent = 100.0;

                //MessageBox.Show(doublePercentPerSecond.ToString() + " " + doubleCurrentDayPercent.ToString() + " Value" + "Dow : " + intDayOfWeek_.ToString());

                switch ((DayOfWeek)(intDayOfWeek_))
                {
                    case DayOfWeek.Monday:
                        UpdateProgreeBar(VPB_Mon, L_Details_Mon, doubleCurrentDayPercent, false, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Tuesday:
                        UpdateProgreeBar(VPB_Tue, L_Details_Tue, doubleCurrentDayPercent, false, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Wednesday:
                        UpdateProgreeBar(VPB_Wed, L_Details_Wed, doubleCurrentDayPercent, false, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Thursday:
                        UpdateProgreeBar(VPB_Thu, L_Details_Thu, doubleCurrentDayPercent, false, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Friday:
                        UpdateProgreeBar(VPB_Fri, L_Details_Fri, doubleCurrentDayPercent, false, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Saturday:
                        UpdateProgreeBar(VPB_Sat, L_Details_Sat, doubleCurrentDayPercent, true, longTimeDiff, longTimeStamp_EndOfDay);
                        break;

                    case DayOfWeek.Sunday:
                        UpdateProgreeBar(VPB_Sun, L_Details_Sun, doubleCurrentDayPercent, true, longTimeDiff, longTimeStamp_EndOfDay);
                        break;
                }

            }



            L_Week_Interval.Text = "" + Utils.Unix.DateTimeFromUnixTimestampSeconds(longTimeStamp_BeginningOfDay).ToLongDateString() +
                    " - " + Utils.Unix.DateTimeFromUnixTimestampSeconds(longTimeStamp_EndOfDay).ToLongDateString();


            double dWHWeek = ((double)((double)lWeekTotalHours / 3600.0));

            L_Week_Summary.Text = "Total WH/week : " + dWHWeek.ToString("#,##") + " / 40";
            if (dWHWeek > 40)
            {
                L_Week_Summary.ForeColor = Color.Red;
            }
            else
            {
                L_Week_Summary.ForeColor = Color.Black;
            }

            
        }

        private void DTP_Filter_ValueChanged(object sender, EventArgs e)
        {
            this.Report_Load(null, null);
        }

        private void B_Date_PreviousDay_Click(object sender, EventArgs e)
        {
            DTP_Filter.Value = DTP_Filter.Value.AddDays(-7);
            this.Report_Load(null, null);
        }

        private void B_Date_NextDay_Click(object sender, EventArgs e)
        {
            DTP_Filter.Value = DTP_Filter.Value.AddDays(7);
            this.Report_Load(null, null);
        }

        private void B_Date_Today_Click(object sender, EventArgs e)
        {
            DTP_Filter.Value = DateTime.Now;
            this.Report_Load(null, null);
        }

        private void B_Report_ProcessAll_Click(object sender, EventArgs e)
        {
            if (BgW_processReport.IsBusy != true)
            {
                BgW_processReport.RunWorkerAsync();
            }
        }

        private void BgW_processReport_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            int intBigReportTimeframeYears = (int)NUM_RangeYearReport.Value;

            long longTimestampFrame = intBigReportTimeframeYears * 365 * 24 * 3600;
            long longTimestampStart = Utils.Unix.GetCurrentUnixTimestampSeconds() - longTimestampFrame;

            double dbCumulatedHours = 0.0;
            int intWorkingDays = 0;
            int intDaysCounter = 0;
            int intWeekEndDaysCounter = 0;

            int int_General_WorkingDays = 0;
            int int_General_WeekEndDaysCounter = 0;

            for (long indexSec = 0; indexSec <= longTimestampFrame; indexSec = indexSec + (24*3600) )
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Perform a time consuming operation and report progress.

                    intDaysCounter++;

                    long longDayTimestamp = longTimestampStart + indexSec;

                    ActivityLogEvents.GetActivityLogWorkingHoursPerDay EventGetListWorkHours = new ActivityLogEvents.GetActivityLogWorkingHoursPerDay();
                    EventGetListWorkHours.setDay(Utils.Unix.DateTimeFromUnixTimestampSeconds(longDayTimestamp));
                    List<double> listDouble = (List<double>)EventGetListWorkHours.Request();

                    if ((double)listDouble[0] != 0.0)
                    {

                        dbCumulatedHours += (double)listDouble[0];

                        if (Utils.Unix.DateTimeFromUnixTimestampSeconds(longDayTimestamp).DayOfWeek != DayOfWeek.Saturday &&
                            Utils.Unix.DateTimeFromUnixTimestampSeconds(longDayTimestamp).DayOfWeek != DayOfWeek.Sunday)
                        {
                            intWorkingDays++;
                        }
                        else
                        {
                            intWeekEndDaysCounter++;
                        }
                    }

                    if (Utils.Unix.DateTimeFromUnixTimestampSeconds(longDayTimestamp).DayOfWeek != DayOfWeek.Saturday &&
                            Utils.Unix.DateTimeFromUnixTimestampSeconds(longDayTimestamp).DayOfWeek != DayOfWeek.Sunday)
                    {
                        int_General_WorkingDays++;
                    }
                    else
                    {
                        int_General_WeekEndDaysCounter++;
                    }

                    worker.ReportProgress(intDaysCounter % 100);
                }
            }

            worker.ReportProgress(100);

            double dbAvgWHperDay = dbCumulatedHours / (double)(intWorkingDays);

            MessageBox.Show(
                "Total days : " + (intDaysCounter).ToString() + "\r\n" +
                "Total working days : " + int_General_WorkingDays.ToString() + "\r\n" +
                "Total Weekend days : " + int_General_WeekEndDaysCounter.ToString() + "\r\n" + "\r\n" +

                "Total days WORKED : " + (intWorkingDays + intWeekEndDaysCounter).ToString() + "\r\n" +
                "Total working days WORKED : " + intWorkingDays.ToString() + "\r\n" +
                "Total Weekend days WORKED : " + intWeekEndDaysCounter.ToString() + "\r\n" +

                "TOTAL Cumulated woring hours : " + dbCumulatedHours.ToString("#.##") + "\r\n" + "\r\n" +

                "Avg. Hours / WORKED Day : " + dbAvgWHperDay.ToString("#.##") + "\r\n"+
                "EXTRA Hours WORKED : " + (dbCumulatedHours - (double)(intWorkingDays*8)).ToString("#.##") + "\r\n",
                
                "Overall report result", MessageBoxButtons.OK, MessageBoxIcon.Information

                );
        }

        private void BgW_processReport_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.L_ReportProgress.Text = (e.ProgressPercentage.ToString() + "%");
        }

        private void BgW_processReport_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                this.L_ReportProgress.Text = "Canceled!";
            }

            else if (!(e.Error == null))
            {
                this.L_ReportProgress.Text = ("Error: " + e.Error.Message);
            }

            else
            {
                this.L_ReportProgress.Text = "Done!";
            }
        }

        private void Report_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (BgW_processReport.WorkerSupportsCancellation == true)
            {
                BgW_processReport.CancelAsync();
            }
        }
    }
}
